#include "compi/context.h"

#include <gtest/gtest.h>

#include <mpi.h>

using namespace compi;

class ContextTest : public ::testing::Test
{
protected:
    void SetUp() override
    {
        // 共享全局 Environment，避免在每个用例结束时析构导致 MPI_Finalize。
        int initialized = 0;
        MPI_Initialized(&initialized);
        if (!initialized)
        {
            int argc = 0;
            char ** argv = nullptr;
            MPI_Init(&argc, &argv);
        }
        static Environment * shared_env = nullptr;
        if (!shared_env)
            shared_env = new Environment();
        env_ = shared_env; // 借用，不拥有
    }

    void TearDown() override
    {
        // 不释放共享的Environment
    }

protected:
    Environment * env_{};
};

TEST_F(ContextTest, BasicCreationAndDestruction)
{
    // 测试Context创建
    auto & ctx = Context::for_comm(MPI_COMM_WORLD, *env_);

    // 测试基本属性访问
    EXPECT_EQ(ctx.comm(), MPI_COMM_WORLD);
    auto env_res = ctx.environment();
    EXPECT_TRUE(env_res.is_success());
    EXPECT_EQ(&env_res.value(), env_);
}

TEST_F(ContextTest, TagAllocatorIntegration)
{
    auto & ctx = Context::for_comm(MPI_COMM_WORLD, *env_);

    // 测试TagAllocator集成
    auto & allocator = ctx.tag_allocator();

    // 创建命名空间
    auto ns = allocator.create_namespace("test_namespace");

    // 请求标签
    auto tag = ns.request();
    EXPECT_GT(tag.value, 0);
    EXPECT_EQ(tag.ns_id, ns.id());

    // 释放标签
    ns.release(tag);
}

TEST_F(ContextTest, MpiCallStats)
{
    auto & ctx = Context::for_comm(MPI_COMM_WORLD, *env_);

    // 重置并获取初始统计快照（按值避免别名）
    ctx.reset_stats();
    auto initial_total_calls = ctx.stats().total_calls;

    // 执行一些MPI调用
    int rank;
    ctx.call_mpi([&]() { return MPI_Comm_rank(MPI_COMM_WORLD, &rank); }, "test_rank");
    int size;
    ctx.call_mpi([&]() { return MPI_Comm_size(MPI_COMM_WORLD, &size); }, "test_size");

    // 检查统计更新（使用值比较）
    auto final_total_calls = ctx.stats().total_calls;
    EXPECT_GE(final_total_calls, initial_total_calls + 2);
}

// 过时特性测试（缓冲池/日志/度量/ContextScope）已移除，遵循新架构。